package com.ecarx.vhaltests.hy11.testcases.info;

import android.car.Car;
import android.car.VehicleAreaType;
import android.car.VehiclePropertyIds;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;
import android.os.SystemProperties;

import androidx.test.platform.app.InstrumentationRegistry;

import com.ecarx.vhaltests.VhalUnitTestBase;
import com.ecarx.xui.adaptapi.car.IWrapper;
import com.ecarx.xui.adaptapi.car.base.ICarInfo;
import com.ecarx.xui.adaptapi.car.property.IProperty;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SystemDeviceInfoTest extends VhalUnitTestBase {
    private static CarPropertyManager mCarPropertyManager;

    private static int mVinPropertyId;
    private static int mIhuidPropertyId;
    private static int mXdsnPropertyId;
    private static int mVehicleTypePropertyId;
    private static int mVehicleConfigPropertyId;
    private static int mSupplierCodePropertyId;
    private static int mProjectCodePropertyId;

    private static boolean mAdaptApiDebugMode;

    private static final String PROPERTY_DEBUG_ADAPTAPI = "persist.adaptapi.debug";
    private static final String PROPERTY_DEBUG_DEVICE_VIN = "persist.device.vin";
    private static final String PROPERTY_DEBUG_DEVICE_IHUID = "persist.device.ihuid";
    private static final String PROPERTY_DEBUG_DEVICE_XDSN = "persist.device.xdsn";
    private static final String PROPERTY_DEBUG_DEVICE_VEHICLE_TYPE = "persist.device.vehicle_type";
    private static final String PROPERTY_DEBUG_DEVICE_VEHICLE_TYPE_CONFIG = "persist.device.vehicle_type_config";
    private static final String PROPERTY_DEBUG_DEVICE_SUPPLIER_CODE = "persist.device.supplier_code";
    private static final String PROPERTY_DEBUG_DEVICE_PROJECT_CODE = "persist.device.pcode";
    private static final String PROPERTY_CARCONFIG_13 = "vhal.carconfig13";
    private static final String PROPERTY_CARCONFIG_158 = "vhal.carconfig158";
    private static final int DEFAULT_CARCONFIG = -1;
    private static final int VEHICLE_TYPE_UNKNOWN = 0;
    private static final int VEHICLE_TYPE_FUEL = 1;
    private static final int VEHICLE_TYPE_HEV = 2;
    private static final int VEHICLE_TYPE_PHEV = 3;
    private static final int VEHICLE_TYPE_MHEV = 7;
    private static final int VEHICLE_TYPE_BEV = 8;
    private static final String DEFAULT_INFO_INVALID = "NOT_VALID";
    private static final String VEHICLE_TYPE_CONFIG_HIGH = "02104S1";
    private static final String VEHICLE_TYPE_CONFIG_LOW = "02104S2";
    private static final String DEFAULT_INFO_SUPPLIER_CODE = "999722";
    private static final String DEFAULT_INFO_PROJECT_CODE = "SHU104S";

    @BeforeClass
    public static void testInit() {
        Car mCar = Car.createCar(mContext);
        mCarPropertyManager = (CarPropertyManager) mCar.getCarManager(Car.PROPERTY_SERVICE);

        IWrapper mWrapper = com.ecarx.xui.adaptapi.car.Car.createWrapper(InstrumentationRegistry.getInstrumentation().getTargetContext());

        mVinPropertyId = VehiclePropertyIds.INFO_VIN;
        mIhuidPropertyId = mWrapper.getWrappedPropertyId(
            IWrapper.WrappedIdType.ID_TYPE_FUNCTION, IProperty.DEVICE_IHUID).getPropertyId();
        mXdsnPropertyId = mWrapper.getWrappedPropertyId(
            IWrapper.WrappedIdType.ID_TYPE_FUNCTION, IProperty.DEVICE_XDSN).getPropertyId();
        mVehicleTypePropertyId = mWrapper.getWrappedPropertyId(
            IWrapper.WrappedIdType.ID_TYPE_FUNCTION, ICarInfo.INT_INFO_VEHICLE_TYPES).getPropertyId();
        mVehicleConfigPropertyId = mWrapper.getWrappedPropertyId(
            IWrapper.WrappedIdType.ID_TYPE_FUNCTION, IProperty.DEVICE_VEHICLE_TYPE_CONFIG).getPropertyId();
        mSupplierCodePropertyId = mWrapper.getWrappedPropertyId(
            IWrapper.WrappedIdType.ID_TYPE_FUNCTION, IProperty.DEVICE_SUPPLIER_CODE).getPropertyId();
        mProjectCodePropertyId = mWrapper.getWrappedPropertyId(
            IWrapper.WrappedIdType.ID_TYPE_FUNCTION, IProperty.DEVICE_PROJECT_CODE).getPropertyId();

        mAdaptApiDebugMode = SystemProperties.getBoolean(PROPERTY_DEBUG_ADAPTAPI, false);
    }

    @Test
    public void test_SystemDeviceInfo_INFO_VIN() {
        CarPropertyValue value = mCarPropertyManager.getProperty(mVinPropertyId, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
        Assert.assertEquals(value.getStatus(), CarPropertyValue.STATUS_AVAILABLE);
        if (mAdaptApiDebugMode) {
            Assert.assertEquals((String) value.getValue(),
                SystemProperties.get(PROPERTY_DEBUG_DEVICE_VIN, DEFAULT_INFO_INVALID));
        } else {
            Assert.assertEquals((String) value.getValue(), DEFAULT_INFO_INVALID);
        }
    }

    @Test
    public void test_SystemDeviceInfo_DEVICE_IHUID() {
        CarPropertyValue value = mCarPropertyManager.getProperty(mIhuidPropertyId, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
        Assert.assertEquals(value.getStatus(), CarPropertyValue.STATUS_AVAILABLE);
        if (mAdaptApiDebugMode) {
            Assert.assertEquals((String) value.getValue(),
                SystemProperties.get(PROPERTY_DEBUG_DEVICE_IHUID, DEFAULT_INFO_INVALID));
        } else {
            Assert.assertEquals((String) value.getValue(), DEFAULT_INFO_INVALID);
        }
    }

    @Test
    public void test_SystemDeviceInfo_DEVICE_XDSN() {
        CarPropertyValue value = mCarPropertyManager.getProperty(mXdsnPropertyId, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
        Assert.assertEquals(value.getStatus(), CarPropertyValue.STATUS_AVAILABLE);
        if (mAdaptApiDebugMode) {
            Assert.assertEquals((String) value.getValue(),
                SystemProperties.get(PROPERTY_DEBUG_DEVICE_XDSN, DEFAULT_INFO_INVALID));
        } else {
            Assert.assertEquals((String) value.getValue(), DEFAULT_INFO_INVALID);
        }
    }

    @Test
    public void test_SystemDeviceInfo_DEVICE_VEHICLE_TYPE() {
        CarPropertyValue value = mCarPropertyManager.getProperty(mVehicleTypePropertyId, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
        Assert.assertEquals(value.getStatus(), CarPropertyValue.STATUS_AVAILABLE);
        if (mAdaptApiDebugMode) {
            Assert.assertEquals((int) value.getValue(),
                    SystemProperties.getInt(PROPERTY_DEBUG_DEVICE_VEHICLE_TYPE, VEHICLE_TYPE_UNKNOWN));
        } else {
            int carconfig13 = SystemProperties.getInt(PROPERTY_CARCONFIG_13, DEFAULT_CARCONFIG);
            if (carconfig13 == 0x01) {
                Assert.assertEquals((int) value.getValue(), VEHICLE_TYPE_FUEL);
            } else if (carconfig13 == 0x02) {
                Assert.assertEquals((int) value.getValue(), VEHICLE_TYPE_HEV);
            } else if (carconfig13 == 0x03) {
                Assert.assertEquals((int) value.getValue(), VEHICLE_TYPE_PHEV);
            } else if (carconfig13 == 0x04) {
                Assert.assertEquals((int) value.getValue(), VEHICLE_TYPE_BEV);
            } else if (carconfig13 == 0x80) {
                Assert.assertEquals((int) value.getValue(), VEHICLE_TYPE_MHEV);
            } else {
                Assert.assertEquals((int) value.getValue(), VEHICLE_TYPE_UNKNOWN);
            }
        }
    }

    @Test
    public void test_SystemDeviceInfo_DEVICE_VEHICLE_TYPE_CONFIG() {
        CarPropertyValue value = mCarPropertyManager.getProperty(mVehicleConfigPropertyId, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
        Assert.assertEquals(value.getStatus(), CarPropertyValue.STATUS_AVAILABLE);
        if (mAdaptApiDebugMode) {
            Assert.assertEquals((String) value.getValue(),
                SystemProperties.get(PROPERTY_DEBUG_DEVICE_VEHICLE_TYPE_CONFIG, VEHICLE_TYPE_CONFIG_HIGH));
        } else {
            int carconfig158 = SystemProperties.getInt(PROPERTY_CARCONFIG_158, DEFAULT_CARCONFIG);
            if (carconfig158 != 0x03) {
                Assert.assertEquals((String) value.getValue(), VEHICLE_TYPE_CONFIG_HIGH);
            } else {
                Assert.assertEquals((String) value.getValue(), VEHICLE_TYPE_CONFIG_LOW);
            }
        }
    }

    @Test
    public void test_SystemDeviceInfo_DEVICE_SUPPLIER_CODE() {
        CarPropertyValue value = mCarPropertyManager.getProperty(mSupplierCodePropertyId, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
        Assert.assertEquals(value.getStatus(), CarPropertyValue.STATUS_AVAILABLE);
        if (mAdaptApiDebugMode) {
            Assert.assertEquals((String) value.getValue(),
                SystemProperties.get(PROPERTY_DEBUG_DEVICE_SUPPLIER_CODE, DEFAULT_INFO_SUPPLIER_CODE));
        } else {
            Assert.assertEquals((String) value.getValue(), DEFAULT_INFO_SUPPLIER_CODE);
        }
    }

    @Test
    public void test_SystemDeviceInfo_DEVICE_PROJECT_CODE() {
        CarPropertyValue value = mCarPropertyManager.getProperty(mProjectCodePropertyId, VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL);
        Assert.assertEquals(value.getStatus(), CarPropertyValue.STATUS_AVAILABLE);
        if (mAdaptApiDebugMode) {
            Assert.assertEquals((String) value.getValue(),
                SystemProperties.get(PROPERTY_DEBUG_DEVICE_PROJECT_CODE, DEFAULT_INFO_PROJECT_CODE));
        } else {
            Assert.assertEquals((String) value.getValue(), DEFAULT_INFO_PROJECT_CODE);
        }
    }
}
